﻿/*
 * This software is the confidential and proprietary
 * information of NetBay
 * Such confidential information should not be disclosed
 * NetBay copyright(c) 2010
 */


#region Using
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using System.ComponentModel.DataAnnotations;
using System.ServiceModel.DomainServices.Server;
#endregion

namespace NetBay.Core.BusinessEntities
{
    [DataContract]
    public class Folder : ReturnObject
    {
        #region Enums
        #endregion

        #region Constants
        #endregion

        #region Attributes
        /// <summary>
        /// Folder Identifier
        /// </summary>
        private long m_lIdentifier;
        /// <summary>
        /// // TD004_iddoc
        /// </summary>
        private string m_sIddoc = string.Empty;
        /// <summary>
        /// Index Valorization for internal usage
        /// </summary>
        private Dictionary<long, string> m_oIndexIdValues = new Dictionary<long, string>();
        /// <summary>
        /// Indexs for valorization
        /// </summary>
        private List<Index> m_oListIndex = new List<Index>();
        /// <summary>
        /// valorizations
        /// </summary>
        private List<string> m_oListValues = new List<string>();
        /// <summary>
        /// Folder Creation Date
        /// </summary>
        private DateTime m_dtCreationDate;
        /// <summary>
        /// Identifier of the user that create the folder
        /// </summary>
        private long m_lCreationUserIdentifier;
        /// <summary>
        /// Date of last modification
        /// </summary>
        private DateTime m_dtModificationDate;
        /// <summary>
        /// User that modified the Folder
        /// </summary>
        private long m_lModificationUserIdentifier;
        /// <summary>
        /// Note attached to the folder
        /// </summary>
        private string m_sNote = string.Empty;
        /// <summary>
        /// State of the Folder
        /// </summary>
        private string m_sState = string.Empty;
        /// <summary>
        /// //TD004_HISTO
        /// </summary>
        private int m_iHisto = 0;
        /// <summary>
        /// Folder Type Identifier
        /// </summary>
        private long m_lFolderTypeIdentifier;
        /// <summary>
        /// Document List
        /// </summary>
        private List<Document> m_lstDocuments;
        /// <summary>
        /// count of Documents in this folder
        /// </summary>
        private int m_iNbDoc;

        private int m_iNbAlert;

        private List<string> m_oFullTextDocList;
        private string m_oFolderDocList;


        [DataMember]
        public string Iddoc
        {
            get { return m_sIddoc; }
            set { m_sIddoc = value; }
        }

        [DataMember]
        public List<Document> LstDocuments
        {
            get { return m_lstDocuments; }
            set { m_lstDocuments = value; }
        }

        [DataMember]
        public string Note
        {
            get { return m_sNote; }
            set {m_sNote = value; }
        }

        [DataMember]
        public string State
        {
            get { return m_sState; }
            set { m_sState = value; }
        }

        [DataMember]
        public int Histo
        {
            get { return m_iHisto; }
            set { m_iHisto = value; }
        }

        [DataMember]
        public long ModificationUserIdentifier
        {
            get { return m_lModificationUserIdentifier; }
            set { m_lModificationUserIdentifier = value; }
        }

        [DataMember]
        public DateTime ModificationDate
        {
            get { return m_dtModificationDate; }
            set { m_dtModificationDate = value; }
        }

        [DataMember]
        public long CreationUserIdentifier
        {
            get { return m_lCreationUserIdentifier; }
            set { m_lCreationUserIdentifier = value; }
        }

        [DataMember]
        public DateTime CreationDate
        {
            get { return m_dtCreationDate; }
            set { m_dtCreationDate = value; }
        }

        /// <summary>
        /// Index Valorization for internal usage
        /// </summary>
        public Dictionary<long, string> IndexIdValues
        {
            get { return m_oIndexIdValues; }
            private set { m_oIndexIdValues = value; }
        }

        /// <summary>
        /// Indexs for valorization
        /// </summary>
        [Association("ListIndex1", "Key", "ForeignKey")]
        [Include]
        [DataMember]
        public List<Index> ListIndex
        {
            get { return m_oListIndex; }
            set 
            { 
                m_oListIndex = value;
                ItemEntity.SetForeignKey(m_oListIndex, Key);
            }
        }

        /// <summary>
        /// valorizations
        /// </summary>
        [DataMember]
        public List<string> ListValues
        {
            get { return m_oListValues; }
            set { m_oListValues = value; }
        }

        [DataMember]
        public long FolderTypeIdentifier
        {
            get { return m_lFolderTypeIdentifier; }
            set { m_lFolderTypeIdentifier = value; }
        }

        [DataMember]
        public long Identifier
        {
            get { return m_lIdentifier; }
            set { m_lIdentifier = value; }
        }

        /// <summary>
        /// count of Documents in this folder
        /// </summary>
        [DataMember]
        public int NbDoc
        {
            get { return m_iNbDoc; }
            set { m_iNbDoc = value; }
        }
        
        /// <summary>
        /// Get the number of alerts attached to this folder
        /// </summary>
        [DataMember]
        public int NbAlert
        {
            get { return m_iNbAlert; }
            set { m_iNbAlert = value; }
        }
        [DataMember]
        public List<string> FullTextDocList
        {
            get { return m_oFullTextDocList; }
            set { m_oFullTextDocList = value; }
        }

        [DataMember]
        public string FolderDocList
        {
            get { return m_oFolderDocList; }
            set { m_oFolderDocList = value; }
        }
        #endregion

        #region Init/Constructor
        /// <summary>
        /// Default constructor 
        /// </summary>
        public Folder()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Folder"/> class for error usages
        /// </summary>
        /// <param name="errorMessage">The error message.</param>
        /// <param name="applicationException">The application exception.</param>
        public Folder(string errorMessage, Exception applicationException = null)
            : base(errorMessage, applicationException)
        {
        }
        #endregion
    
    
        #region Functions

        #region Publics
        /// <summary>
        /// Indicate whether the folder match with all regular expression for values items
        /// </summary>
        /// <param name="p_oDicOfRegularExpression">Association of Item and regular expression</param>
        /// <returns>true if match otherwise false</returns>
        public bool IsMatch(Dictionary<long, Regex> p_oDicOfRegularExpression)
        {
            bool l_bRet = true;

            try
            {
                // Loop over all regular expression
                foreach (KeyValuePair<long, Regex> l_oKvp in p_oDicOfRegularExpression)
                {
                    // Retreive the value
                    if (l_oKvp.Value.IsMatch(IndexIdValues[l_oKvp.Key]) == false)
                    {
                        //int a = 5;
                        l_bRet = false;
                        break;
                    }

                    //if (string.IsNullOrEmpty(l_oKvp.Value.ToString()) == false)
                    //{
                    //    if (ExactMatch(l_oKvp.Value.ToString(), IndexIdValues[l_oKvp.Key]) == false)
                    //    {
                    //        l_bRet = false;
                    //        break;
                    //    }
                    //}

                }
            }
            catch (Exception ex)
            {
                throw new Exception(this.ToString(), ex);
            }

            return l_bRet;
        }

        private static bool ExactMatch(string input, string match)
        {
            string l_szMatchFormat = string.Format(@"\b{0}\b", Regex.Escape(match));
            bool l_bRet = Regex.IsMatch(input, l_szMatchFormat);
            return l_bRet;
        }



        /// <summary>
        /// Set the association of indexs and values
        /// </summary>
        /// <param name="p_oDicIndexValues">Association of indexs and values</param>
        public void SetIndexValues(Dictionary<Index, string> p_oDicIndexValues)
        {
            // Delete old values
            ListIndex.Clear();
            ListValues.Clear();
            // Add values in lists
            List<Index> l_oIndexs = new List<Index>(p_oDicIndexValues.Count);       // this is explicit !!!
            List<string> l_oValues = new List<string>(p_oDicIndexValues.Count);     // For normalization
            foreach (KeyValuePair<Index, string> l_oKvp in p_oDicIndexValues)
            {
                l_oIndexs.Add(l_oKvp.Key);
                l_oValues.Add(l_oKvp.Value);
            }
            // Affect lists to their properties
            ListIndex = l_oIndexs;
            ListValues = l_oValues;
            // Rebuild the 'IndexIdValues'
            List<Index>.Enumerator l_oEnumeratorIndex = ListIndex.GetEnumerator();
            List<string>.Enumerator l_oEnumeratorValue = ListValues.GetEnumerator();
            for (int i = 0; i < ListIndex.Count; i++)
            {
                // Move to next values
                if (l_oEnumeratorIndex.MoveNext() == false)
                    break;
                if (l_oEnumeratorValue.MoveNext() == false)
                    break;
                // Insert the association into 'IndexIdValues'
                IndexIdValues.Add(l_oEnumeratorIndex.Current.Indentifier, l_oEnumeratorValue.Current);
            }
        }
        #endregion

        #region Privates
        #endregion

        #endregion

        public override object Clone()
        {
            throw new NotImplementedException();
        }
    }

    public abstract class FolderDer : Folder
    {
        //Set the valorization of all indexes
        public abstract void SetIndexValorization();

        /// <summary>
        /// Set all documents for this Folder
        /// </summary>
        /// <param name="p_lUserId">User ID</param>
        /// <param name="p_lFolderTypeId">FolderType ID</param>
        public abstract void SetDocumentList(long p_lUserId, long p_lFolderTypeId);
    }
}
